<?php
// ListingController
namespace App\Controllers;

use Framework\Database;
use Framework\Validation;
use Framework\Session;
use Framework\Authorisation;
use Framework\Middleware\Authorise;

class ListingController
{
    protected $db;

    public function __construct()
    {
        $config = require basePath('config/db.php');
        $this->db = new Database($config);
    }

    /**
     * 展示所有岗位
     * 
     * @return void
     */
    public function index()
    {
        $listings = $this->db->query('SELECT * FROM listing ORDER BY created_at DESC ')->fetchAll();
        loadView('listings/index', ['listings' => $listings]);
    }

    /**
     * 展示创建职位表单
     * 
     * @return void
     */

    public function create()
    {
        loadView('listings/create');
    }

    /**
     * 展示单一岗位页面
     * 
     * @return void
     */
    public function show($params)
    {
        $id = $params['id'] ?? '';
        $params = ['id' => $id];
        $listing = $this->db->query('SELECT * FROM listing WHERE id = :id', $params)->fetch();

        //检查listing是否存在
        if (!$listing) {
            ErrorController::notFound('该岗位不存在！');
            return;
        }

        loadView('listings/show', ['listing' => $listing]);
    }

    /**
     * 存储数据到数据库
     * 
     * @return void
     */
    public function store()
    {
        $allowedFields = ['title', 'description', 'salary', 'tags', 'company', 'address', 'city', 'province', 'phone', 'email', 'requirements', 'benefits'];

        //从$_POST中提取允许的参数
        $newListingData = array_intersect_key($_POST, array_flip($allowedFields));

        //设置用户ID
        $newListingData['user_id'] = Session::get('user')['id'];

        //清洗数据
        $newListingData = array_map('sanitize', $newListingData);

        //定义必须的字段
        $requiredFields = ['title', 'description', 'email', 'city', 'province'];

        //检查必须的字段
        $errors = [];
        foreach ($requiredFields as $field) {
            if (empty($newListingData[$field]) || !Validation::string($newListingData[$field])) {
                $errors[$field] = ucfirst($field) . ' is required.';
            }
        }

        //处理可能的错误
        if (!empty($errors)) {
            //重加载创建列表视图并显示错误
            loadView('listings/create', [
                'errors' => $errors,
                'listing' => $newListingData
            ]);
        } else {
            //初始化数组收集字段名称，为了sql查询
            $fields = array();

            // Collecting new listing data
            foreach ($newListingData as $field => $value) {
                $fields[] = $field;
            }

            //数组转字符串
            $fields = implode(', ', $fields);

            //收集占位符
            $values = array();

            // Assigning null to empty fields in new listing data
            foreach ($newListingData as $field => $value) {
                if ($value === '') {
                    $newListingData[$field] = null;
                }
                $values[] = ':' . $field;
            }

            //占位符转字符串
            $values = implode(', ', $values);

            //sql插入语句
            $query = "INSERT INTO listing ({$fields}) VALUES ({$values})";

            //执行
            $this->db->query($query, $newListingData);

            Session::setFlashMessage('success_message', 'Create new listing successfully');

            //重定向
            redirect('/listings');
        }
    }

    /**
     * Destroys a listing from the database.
     *
     * @param array $params Parameters including the 'id' of the listing to be deleted.
     * @return void
     */
    public function destroy($params)
    {
        $id = $params['id'];
        $params = [
            'id' => $id
        ];
        $listing = $this->db->query('SELECT * FROM listing WHERE id = :id', $params)->fetch();
        if (!$listing) {
            ErrorController::notFound('Listing not found.');
            return;
        }

        // Verify ownership of the listing
        if (!Authorisation::isOwner($listing->user_id)) {
            inspect($_SESSION);
            Session::setFlashMessage('error_message', 'Destroy failed: you can destroy your listing only.');
            return redirect('/listings/' . $listing->id);
        }

        // Delete the listing from the database
        $this->db->query('DELETE FROM listing WHERE id = :id', $params);

        //提示信息
        Session::setFlashMessage('error_message', 'Destroy listing successfully');

        // Redirect to the listings page
        redirect('/listings');
    }

    /**
     * Edit the listing with the given parameters.
     *
     * @param array $params Parameters including 'id' and other listing details.
     * @return void
     */
    public function edit($params)
    {
        $id = $params['id'] ?? '';

        if (!$id) {
            ErrorController::notFound('Listing not found.');
            return;
        }
        $params = ['id' => $id];
        $listing = $this->db->query('SELECT * FROM listing WHERE id = :id', $params)->fetch();
        if (!$listing) {
            ErrorController::notFound('Listing not found.');
            return;
        }

        // Verify ownership of the listing
        if (!Authorisation::isOwner($listing->user_id)) {
            Session::setFlashMessage('error_message', 'Edit failed: you can edit your listing only.');
            return redirect('/listings/' . $listing->id);
        }

        // Edit the listing
        loadView('listings/edit', ['listing' => $listing]);
    }

    /**
     * Update the listing with the given parameters
     * 
     *@param array $params Parameters including 'id' and other listing details.
     *@return void
     */
    public function update($params)
    {
        $id = $params['id'] ?? '';
        $params = [
            'id' => $id
        ];
        $listing = $this->db->query('SELECT * FROM listing WHERE id = :id', $params)->fetch();
        if (!$listing) {
            ErrorController::notFound("Listing not found.");
            return;
        }

        // Verify ownership of the listing
        if (!Authorisation::isOwner($listing->user_id)) {
            Session::setFlashMessage('error_message', 'Update failed: you can update your listing only.');
            return redirect('/listings/' . $listing->id);
        }

        $allowedFields = ['title', 'description', 'salary', 'tags', 'company', 'address', 'city', 'province', 'phone', 'email', 'requirements', 'benefits'];
        $updateValues = array_intersect_key($_POST, array_flip($allowedFields));
        $updateValues = array_map('sanitize', $updateValues);
        $requiredFields = ['title', 'description', 'salary', 'email', 'city', 'province'];
        $errors = [];
        foreach ($requiredFields as $field) {
            if (empty($updateValues[$field]) || !Validation::string($updateValues[$field])) {
                $errors[$field] = ucfirst($field) . ' is required.';
            }
        }

        if (!empty($errors)) {
            loadView('listings/edit', [
                'listing' => $listing,
                'errors' => $errors
            ]);
            exit;
        } else {
            $updateFields = [];
            foreach (array_keys($updateValues) as $field) {
                $updateFields[] = "{$field} = :{$field}";
            }
            $updateFields = implode(', ', $updateFields);
            $updateQuery = "UPDATE listing SET $updateFields WHERE id = :id";
            $updateValues['id'] = $id;
            $this->db->query($updateQuery, $updateValues);

            Session::setFlashMessage('success_message', 'Update listing successfully');
            redirect("/listings/" . $id);
        }
    }

    /**
     * Search for a listing
     * @return void 
     */
    public function search()
    {
        $keywords = isset($_GET['keywords']) ? trim($_GET['keywords']) : '';
        $location = isset($_GET['location']) ? trim($_GET['location']) : '';

    $query = "SELECT * FROM Listing WHERE
              (title LIKE :keywords OR
              description LIKE :keywords OR
              tags LIKE :keywords OR
              company LIKE :keywords) AND
              (city LIKE :location OR
              province LIKE :location)";

        $params = [
            'keywords' => '%' . $keywords . '%',
            'location' => '%' . $location . '%'
        ];

        $listings = $this->db->query($query, $params)->fetchAll();
        loadView('listings/index', [
            'listings' => $listings,
            'keywords' => $keywords,
            'location' => $location
        ]);
    }
}